home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample SMSAM / SampleSMSAM Source / VirtualFile / VirtualRamOrDiskFile.cp < prev    next >
Encoding:
Text File  |  1995-07-28  |  9.0 KB  |  366 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        VirtualRamOrDiskFile.cp
  3.  
  4.     Copyright:    © 1991-1994 by Apple Computer, Inc.
  5.                 All rights reserved.
  6.  
  7.     Part of the AOCE Sample SMSAM Package.  Consult the license
  8.     which came with this software for your specific legal rights.
  9.  
  10. */
  11.  
  12.  
  13.  
  14. #ifndef __VIRTUALRAMORDISKFILE__
  15. #include "VirtualRamOrDiskFile.h"
  16. #endif
  17.  
  18. #ifndef __ERRORS__
  19. #include <Errors.h>
  20. #endif
  21.  
  22. #ifndef __RAMFILE__
  23. #include "RamFile.h"
  24. #endif
  25.  
  26. #ifndef __ABSTRACTFILE__
  27. #include "AbstractFile.h"
  28. #endif
  29.  
  30. #ifndef    __STDIO__
  31. #include "StdIO.h"
  32. #endif
  33.  
  34. #ifndef    __THREADITULITIES__
  35. #include "ThreadUtilities.h"
  36. #endif
  37.  
  38. #ifndef    __DEBUGGINGGEAR__
  39. #include "DebuggingGear.h"
  40. #endif
  41.  
  42. #ifndef __LIMITS__
  43. #include <Limits.h>
  44. #endif
  45.  
  46. /***********************************|****************************************/
  47.  
  48. #pragma segment VirtualFile
  49.  
  50. DeclareList(TVirtualRamOrDiskFile,TVirtualRamOrDiskFileList);
  51. ImplementList(TVirtualRamOrDiskFile,TVirtualRamOrDiskFileList,false);
  52.  
  53. /***********************************|****************************************/
  54.  
  55. TVirtualRamOrDiskFileList            gVirtualRamOrDiskFileList;
  56.  
  57. /***********************************|****************************************/
  58.  
  59. FSSpec TVirtualRamOrDiskFile::gDefaultStorageLocation;
  60.  
  61. /***********************************|****************************************/
  62.  
  63. extern ostream& DumpHex (ostream& s, const void *p, unsigned long size);
  64.  
  65. /***********************************|****************************************/
  66.  
  67. inline long min ( long a, long b )
  68. {
  69.     return ( a < b) ? a : b;
  70. }
  71.  
  72. /***********************************|****************************************/
  73.  
  74. ostream& TVirtualRamOrDiskFile::operator >> ( ostream& s ) const
  75. {
  76.     s << "TVirtualRamOrDiskFile @ " << ( void*) this;
  77.     return s << ", " << TAbstractFile::operator >> ( s );
  78. }
  79.  
  80. /***********************************|****************************************/
  81.  
  82. TVirtualRamOrDiskFile::TVirtualRamOrDiskFile ( Location location ):
  83.     TVirtualFile (),
  84.     fFile ( nil ),
  85.     fLocation ( location ),
  86.     fRamLimit ( 64 * 1024 ),
  87.     fLength ( 0 )
  88. {
  89.     fFile = fLocation == kMemory ? new TRamFile : CreateDiskFile ();
  90.     fFile->GetEnd ( fLength );
  91.     
  92.     gVirtualRamOrDiskFileList.Append ( this );
  93. }
  94.  
  95. /***********************************|****************************************/
  96.  
  97. TVirtualRamOrDiskFile::TVirtualRamOrDiskFile ( Location location, unsigned long ramToDiskThreshold ):
  98.     TVirtualFile (),
  99.     fFile ( nil ),
  100.     fLocation ( location ),
  101.     fRamLimit ( ramToDiskThreshold ),
  102.     fLength ( 0 )
  103. {
  104.     fFile = (fLocation == kMemory) ? new TRamFile : CreateDiskFile ();
  105.     fFile->GetEnd ( fLength );
  106.     
  107.     gVirtualRamOrDiskFileList.Append ( this );
  108.  
  109. }
  110.  
  111. /***********************************|****************************************/
  112.  
  113. TVirtualRamOrDiskFile::~TVirtualRamOrDiskFile()
  114. {
  115.     gVirtualRamOrDiskFileList.Remove ( this );
  116.     
  117.     delete fFile; 
  118. }
  119.  
  120. /***********************************|****************************************/
  121.  
  122. OSErr TVirtualRamOrDiskFile::SetMaxMemSize ( unsigned long threshold )
  123. {
  124.     fRamLimit = threshold;
  125.     return ( fLocation == kMemory ) && ( fLength > fRamLimit ) ? ForceToDisk () : noErr;
  126. }
  127.  
  128. /***********************************|****************************************/
  129.  
  130. char* LocationStr ( const TVirtualRamOrDiskFile::Location& location )
  131. {
  132.     if (location == TVirtualRamOrDiskFile::kMemory)
  133.         return "inMemory";
  134.     if (location == TVirtualRamOrDiskFile::kDisk)
  135.         return "onDisk";
  136.     return "location ???";
  137. }
  138.  
  139. /***********************************|****************************************/
  140.  
  141. unsigned long GetFilePosition(TAbstractFile* file )
  142. {    long pos;
  143.     OSErr err = file->GetPosition ( pos );
  144.     if (err)
  145.         pos = 0;
  146.     return pos;
  147. }
  148.  
  149. /***********************************|***************************************/
  150.  
  151. unsigned long TVirtualRamOrDiskFile::GetVirtualRamOrDiskFilesCount ( )
  152.  
  153. {    
  154.     return gVirtualRamOrDiskFileList.Count();
  155. }
  156.  
  157. /**********************************|***************************************/
  158.  
  159. unsigned long TVirtualRamOrDiskFile::GetVirtualRamOrDiskFilesSize ( )
  160. {    unsigned long virtualRamOrDiskFilesSize = 0;
  161.  
  162.     unsigned long count = gVirtualRamOrDiskFileList.Count();
  163.     for (unsigned int index = 1; index <= count; index++ )
  164.         {
  165.         TVirtualRamOrDiskFile* vF = gVirtualRamOrDiskFileList.Get ( index );
  166.         
  167.         long fileLength;
  168.         if ( vF->GetEnd ( fileLength ) == noErr )
  169.             virtualRamOrDiskFilesSize += fileLength;
  170.         }
  171.     return virtualRamOrDiskFilesSize;
  172. }
  173.  
  174.  
  175. /***********************************|****************************************/
  176.  
  177. OSErr TVirtualRamOrDiskFile::ReadData ( void* buffer, long& count )
  178. {
  179.     #if debug
  180.     if (steveFlag.Flag(18)) {
  181.         keith << "TVRamOrDiskFile: Read(" << count << ")  fPos=" << GetFilePosition(fFile) << " " << LocationStr(fLocation) << endl;
  182.     }
  183.     #endif
  184.     
  185.     OSErr err = fFile ? fFile->ReadData ( buffer, count ) : fnOpnErr;
  186.  
  187.     #if debug
  188.     if (steveFlag.Flag(18)) {
  189.         keith << "TVRamOrDiskFile: Read, err=" << err << " DATA (" << count << ")  fPos=" << GetFilePosition(fFile) << " " << LocationStr(fLocation) << endl;
  190.         
  191.         DumpHex (keith, buffer, min ( count, 16 ) );
  192.     }
  193.     #endif
  194.  
  195.     return err;    
  196. }
  197.  
  198. /***********************************|****************************************/
  199.  
  200. OSErr TVirtualRamOrDiskFile::WriteData ( const void* buffer, long& count )
  201. {
  202.     OSErr error;
  203.         
  204.     if ( fFile == nil )
  205.         error = fnOpnErr;
  206.     else if ( ( fLocation == kMemory ) && ( ( fLength + count ) > fRamLimit ) )
  207.         error = ForceToDisk ();    
  208.     else
  209.         error = noErr;
  210.  
  211.     #if debug
  212.     if (steveFlag.Flag(18)) {
  213.         keith << "TVRamOrDiskFile: Write(" << count << ")  fPos=" << GetFilePosition(fFile) << " " << LocationStr(fLocation) << endl;
  214.         DumpHex (keith, buffer, min ( count, 16 ) );
  215.     }
  216.     #endif
  217.     
  218.     if ( !error )
  219.         error = fFile->WriteData ( buffer, count );
  220.         
  221.     #if debug
  222.     if (steveFlag.Flag(18)) {
  223.         keith << "TVRamOrDiskFile:Write, done. err=" << error << " count=" << count << "  fPos=" << GetFilePosition(fFile) << " " << LocationStr(fLocation) << endl;
  224.     }
  225.     #endif
  226.  
  227.     fLength += count;
  228.  
  229.     return error;
  230. }
  231.  
  232. /***********************************|****************************************/
  233.  
  234. OSErr TVirtualRamOrDiskFile::SetEnd ( long end ) 
  235. {
  236.     OSErr error;
  237.     
  238.     if ( fFile == nil )
  239.         error = fnOpnErr;
  240.     else if ( ( fLocation == kMemory ) && ( end > fRamLimit ) )
  241.         error = ForceToDisk ();    
  242.     else
  243.         error = noErr;
  244.  
  245.     if ( !error )
  246.         error = fFile->SetEnd ( end );
  247.  
  248.     if ( !error )
  249.         fLength = end;
  250.  
  251.     return error;
  252. }
  253.  
  254. /***********************************|****************************************/
  255.  
  256. OSErr TVirtualRamOrDiskFile::GetEnd ( long& end ) const
  257. {
  258.     return fFile ? fFile->GetEnd ( end ) : fnOpnErr;
  259. }
  260.  
  261. /***********************************|****************************************/
  262.  
  263. OSErr TVirtualRamOrDiskFile::SetPosition ( short mode, long offset )
  264. {
  265.     return fFile ? fFile->SetPosition ( mode, offset ) : fnOpnErr;
  266. }
  267.  
  268. /***********************************|****************************************/
  269.  
  270. OSErr TVirtualRamOrDiskFile::GetPosition ( long& position ) const
  271. {
  272.     return fFile ? fFile->GetPosition ( position ) : fnOpnErr;
  273. }
  274.  
  275. /***********************************|****************************************/
  276.  
  277. OSErr TVirtualRamOrDiskFile::ForceTo ( Location location, TAbstractFile* newFile )
  278. {
  279.     OSErr error = noErr;
  280.     
  281.     if ( fFile )
  282.     {
  283.         FAILNULL ( newFile );
  284.         
  285.         error = newFile->SetEnd ( 0 );
  286.         
  287.         if ( !error )
  288.             error = fFile->WriteTo ( *newFile );
  289.         
  290.         if ( !error )
  291.         {
  292.             delete fFile;
  293.             fFile = newFile;
  294.             fLocation = location;
  295.         }
  296.         else
  297.         {
  298.             delete newFile;
  299.         }
  300.     }
  301.     else
  302.         error = fnOpnErr;
  303.     
  304.     return error;
  305. }
  306.  
  307. /***********************************|****************************************/
  308.  
  309. OSErr TVirtualRamOrDiskFile::ForceToDisk () 
  310. {    
  311.     keithF(18, "TVRamOrDiskFile:: ForceToDisk()" );
  312.     return fLocation != kDisk ? ForceTo ( kDisk, CreateDiskFile () ) : noErr;
  313. }
  314.  
  315. /***********************************|****************************************/
  316.  
  317. OSErr TVirtualRamOrDiskFile::ForceToMemory ()
  318. {
  319.     keithF(18, "TVRamOrDiskFile:: ForceToDisk()" );
  320.     return fLocation != kMemory ? ForceTo ( kMemory, new TRamFile ) : noErr;
  321. }
  322.  
  323. /***********************************|****************************************/
  324.  
  325. void TVirtualRamOrDiskFile::UniqueFileName ( StringPtr name )
  326. {
  327.     static unsigned long gUniqueFileID = 0;
  328.     name [ 0 ] = sprintf ( (char*) &name [ 1 ], "TEMP-%li", ++gUniqueFileID );
  329. }
  330.  
  331. /***********************************|****************************************/
  332.  
  333. TAbstractFile* 
  334. TVirtualRamOrDiskFile::CreateDiskFile ()
  335. {
  336.     UniqueFileName ( gDefaultStorageLocation.name );
  337.     return new TForkFile ( gDefaultStorageLocation );
  338. }
  339.  
  340. /***********************************|****************************************/
  341. void  TVirtualRamOrDiskFile::ForceFreeMemory (unsigned long neededFreeSpace )
  342.     Location    location= kMemory ;
  343.     unsigned long amountFreed = 0;
  344.     unsigned long previousLastUsed = ULONG_MAX;
  345.     
  346.     unsigned long count = gVirtualRamOrDiskFileList.Count();
  347.     for (unsigned int index = 1; index <= count; index++ )
  348.     {
  349.         while (amountFreed < neededFreeSpace) 
  350.         {    
  351.             TVirtualRamOrDiskFile* vF = gVirtualRamOrDiskFileList.Get ( index );
  352.             if ( ( vF->GetLocation() == kMemory) && (vF->LastUsed() < previousLastUsed)  )
  353.             { 
  354.                 previousLastUsed = vF->LastUsed();
  355.                 long fileLength;
  356.                 if ( vF->GetEnd ( fileLength ) == noErr ) {
  357.                     OSErr error = vF->ForceToDisk();
  358.                 
  359.                     amountFreed += fileLength;
  360.                 }
  361.             }
  362.         }
  363.     }
  364. }
  365.